/*
	Written By Pradipna Nepal
	www.pradsprojects.com

	Copyright (C) 2012 Prads Projects
	Please read COPYING.txt included along with this source code for more detail.
	If not included, see http://www.gnu.org/licenses/
*/

#ifndef LIBPARSER_H
#define LIBPARSER_H

#include <list>
#include <stack>
#include <string>
#include <vector>
#include "resIR.h"
#include "libToken.h"
#include "libTokenModule.h"
#include "libPrintError.h"
using namespace std;

#define setRegX(out, index) {\
	out &= 0xFF0;\
	out |= index;\
}

#define setRegY(out, index) {\
	out &= 0xF0F;\
	out |= (index << 4);\
}

#define setRegZ(out, index) {\
	out &= 0xFF;\
	out |= (index << 8);\
}

/*
	ir - Intermediate representation
	regs - X, Y, and/or Z regs. Format is 0xZZYYXX
	operand - Tokens needed for some IR
	label - loword contains label number, hiword contains label for JUMP instructions
	address - loword contains size of binary code to be generated, hiword contains address in the module
*/
struct Opcode {
	OpcodesIR ir;
	int regs;
	vector<Token> operand;
	int label, address;
};

class Parser {
private:
	const TokenLines *tokenLine;
	list<Opcode> *instructions;
	int tCounter, regCounter;
	int label;
	stack<int> lblStackIn, lblStackOut;

	bool loadToReg();

	bool add();
	bool subtract();

	bool highPrecedence();
	bool multiply();
	bool divide();
	bool bitAND();
	bool bitOR();
	bool bitXOR();

	bool condition(int c);
	
	bool expression();
	bool init();

public:
	Parser();

	bool parseToIR(list<Opcode> *irLine, const TokenLines *tokens);
	
	void reset();
	void setTokenCounter(int tCounter);

	void pushLabels(bool in, bool out);
	int getLabelOut(bool pop);
	int getLabelIn(bool pop);
	int getCurrentLabel(bool increment);
};

#endif